package com.back.demo.service;

import com.alibaba.excel.EasyExcel;
import com.back.demo.mapper.AdminMapper;
import com.back.demo.service.MyEasyExcel.*;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@org.springframework.stereotype.Service
public class AdminService {

    @Value("${file.upload-path}")
    private String relativeUploadPath;

    @Value("${file.allowed-types}")
    private String allowedTypes;

    @Value("${file.max-size}")
    private long maxFileSize;

    @Autowired
    private AdminMapper adminMapper;

    public String upload(MultipartFile file) throws IOException {
        String absoluteUploadPath = System.getProperty("user.dir") + File.separator + relativeUploadPath;
        if (file == null || file.isEmpty()) {
            return "上传文件不能为空";
        }

        if (!StringUtils.hasText(absoluteUploadPath)) {
            return "文件上传路径未配置";
        }

        if (!isFileTypeAllowed(file)) {
            return "不允许上传该文件类型";
        }

        if (!isFileContentValid(file)) {
            return "文件内容不合法";
        }

        if (file.getSize() > maxFileSize) {
            return "文件大小超过限制";
        }

        try {
            // String fileName = generateUniqueFileName(file.getOriginalFilename());
            String fileName = file.getOriginalFilename();
            String filePath = absoluteUploadPath + File.separator + fileName;
            File dest = new File(filePath);
            file.transferTo(dest);

            // 将文件名保存到数据库中
            return "文件上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            throw new IOException("文件上传失败");
        }
    }

    private boolean isFileTypeAllowed(MultipartFile file) {
        String fileExtension = getFileExtension(file.getOriginalFilename());
        if (fileExtension != null) {
            List<String> allowedExtensions = Arrays.asList(allowedTypes.split(","));
            return allowedExtensions.contains(fileExtension.toLowerCase());
        }
        return false;
    }

    private boolean isFileContentValid(MultipartFile file) throws IOException {
        // 验证文件类型是否为图像类型
/*        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("image/")) {
            return false;
        }

        // 进一步验证文件内容，例如使用文件头、魔术数字等方式*/
        byte[] fileBytes = file.getBytes();

        if (fileBytes.length >= 4) {
//            byte[] jpegHeader = {(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE0};
//            byte[] pngHeader = {(byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
            byte[] xlsxHeader = {(byte) 0x50, (byte) 0x4B, (byte) 0x03, (byte) 0x04};
//            return startsWith(fileBytes, xlsxHeader) || startsWith(fileBytes, pngHeader);
            return startsWith(fileBytes, xlsxHeader);
        }

        return false;
    }

    private boolean startsWith(byte[] array, byte[] prefix) {
        if (array.length < prefix.length) {
            return false;
        }
        for (int i = 0; i < prefix.length; i++) {
            if (array[i] != prefix[i]) {
                return false;
            }
        }
        return true;
    }

    private String generateUniqueFileName(String originalFileName) {
        String fileExtension = getFileExtension(originalFileName);
        String uniqueFileName = UUID.randomUUID().toString();
        if (fileExtension != null) {
            uniqueFileName += "." + fileExtension;
        }
        return uniqueFileName;
    }

    private String getFileExtension(String fileName) {
        if (StringUtils.hasText(fileName)) {
            int dotIndex = fileName.lastIndexOf(".");
            if (dotIndex >= 0 && dotIndex < fileName.length() - 1) {
                return fileName.substring(dotIndex + 1);
            }
        }
        return null;
    }

    public String importStudentInfo(String fileName) {
        String filePath = System.getProperty("user.dir") + File.separator + relativeUploadPath + File.separator + fileName;
        StudentInfoListener listener = new StudentInfoListener();
        EasyExcel.read(filePath, StudentInfoX.class, listener).sheet(0).doRead();
        ArrayList<StudentInfoX> list = listener.getList();
        for (StudentInfoX i : list) {
            Integer userId = adminMapper.getUserId(i.getStudentId());
            if (userId == null){
                //System.out.println(i);
                adminMapper.userImport(i);
                userId = adminMapper.getUserId(i.getStudentId());
                i.setUserId(userId);
                adminMapper.roleImport(userId);
                adminMapper.infoImport(i);
                adminMapper.summaryImport(userId);
                adminMapper.scoreImport(userId);
            }
        }
        //System.out.println(list);
        return "导入学生信息成功";
    }

    public void exportScore(String fileName) {
        String filePath = System.getProperty("user.dir") + File.separator + relativeUploadPath + File.separator + fileName;
        try {
            //利用poi生成一个空的xlsx文件
            // 创建工作簿
            Workbook workbook = new XSSFWorkbook();
            // 创建工作表
            Sheet sheet = workbook.createSheet("学生成绩");
            // 创建文件输出流
            FileOutputStream fileOutputStream = new FileOutputStream(filePath);
            // 写入文件
            workbook.write(fileOutputStream);
            // 关闭文件输出流和工作簿
            fileOutputStream.close();
            workbook.close();

            List<StudentScoreInfoX> list = adminMapper.scoreExport();
            System.out.println(list.get(1));
            // EasyExcel.write(filePath, StudentScoreInfoX.class).sheet("学生成绩").doWrite(adminMapper.scoreExport());
            EasyExcel.write(filePath, StudentScoreInfoX.class).sheet("学生成绩").doWrite(list);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void download(HttpServletResponse response, String fileName) {
        String filePath = System.getProperty("user.dir") + File.separator + relativeUploadPath + File.separator + fileName;
        // 生成要下载的文件...
        response.setContentType("application/octet-stream");
        // 设置文件名,浏览器会显示下载对话框并使用该文件名
        response.setHeader("Content-Disposition","attachment;"+ filePath);
//        response.setHeader("Content-Disposition","attachment; filename=demo.xlsx");
        // 获取文件输入流
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(filePath);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        // 流传输
        try {
            IOUtils.copy(inputStream, response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String importStudentScore(String fileName) {
        String filePath = System.getProperty("user.dir") + File.separator + relativeUploadPath + File.separator + fileName;
        ImportScoreInfoListener listener= new ImportScoreInfoListener();
        EasyExcel.read(filePath, ImportScoreInfoX.class, listener).sheet(0).doRead();
        ArrayList<ImportScoreInfoX> list = listener.getList();
        for (ImportScoreInfoX i : list) {

            adminMapper.gpaImport(i);
            //System.out.println(i);
        }
        //System.out.println(list);
        return "导入GPA成功";
    }
}
